﻿using ControlCore;
using ControlCore.Controller;
using ControlCore.Device;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using System;
using System.IO;
using System.Windows;

namespace BEControlCenter.UnitTests
{
    [TestClass]
    public class MainWindowVMTests
    {
        [TestInitialize]
        public void TestInit()
        {
            Directory.CreateDirectory("Extensions");
        }

        [TestCleanup]
        public void TestCleanup()
        {
            Directory.Delete("Extensions");
        }

        [TestMethod]
        public void MainWindowVMCtor_Success()
        {
            var mainWindowVM = new MainWindowVM();
        }

        /// <summary>
        /// Test if initialization calls all needed methods etc.
        /// </summary>
        [TestMethod]
        public void MainWindowVMInitCommand_Success()
        {
            //// Create objects and mocks
            var moqRepository = new MockRepository(MockBehavior.Strict);
            var moqController = moqRepository.Create<IController>();
            var moqDevice = moqRepository.Create<IDevice>();
            var mainWindowVM = new MainWindowVM();
            //// setup
            moqController.Setup(x => x.Init()).Verifiable();
            moqController.SetupGet<FrameworkElement>(x => x.ControllerOutput).Returns(new FrameworkElement()).Verifiable();
            mainWindowVM.SelectedController = new Lazy<IController, IControllerMetadata>(() => moqController.Object, null);
            moqDevice.Setup(x => x.Init()).Verifiable();
            moqDevice.SetupGet<FrameworkElement>(x => x.DeviceOutput).Returns(new FrameworkElement()).Verifiable();
            mainWindowVM.SelectedDevice = new Lazy<IDevice, IDeviceMetadata>(() => moqDevice.Object, null);

            var initCommand = mainWindowVM.InitCommand;
            Assert.IsTrue(initCommand.CanExecute(null));
            initCommand.Execute(null);
            moqRepository.VerifyAll();
        }

        /// <summary>
        /// Test if shutdow calls all needed methods etc.
        /// Exception is expected as method tries to call 
        /// Application.Current.Shutdown() which is null for test.
        /// </summary>
        [TestMethod]
        [ExpectedException(typeof(System.NullReferenceException))]
        public void MainWindowVMShutdownCommand_Success()
        {
            //// Create objects and mocks
            var moqRepository = new MockRepository(MockBehavior.Strict);
            var moqController = moqRepository.Create<IController>();
            var moqDevice = moqRepository.Create<IDevice>();
            var mainWindowVM = new MainWindowVM();
            //// setup
            moqController.Setup(x => x.Close()).Verifiable();
            mainWindowVM.SelectedController = new Lazy<IController, IControllerMetadata>(() => moqController.Object, null);
            moqDevice.Setup(x => x.Close()).Verifiable();
            mainWindowVM.SelectedDevice = new Lazy<IDevice, IDeviceMetadata>(() => moqDevice.Object, null);

            var shutdownCommand = mainWindowVM.ShutdownCommand;
            Assert.IsTrue(shutdownCommand.CanExecute(null));
            shutdownCommand.Execute(null);
            moqRepository.VerifyAll();
        }
    }
}
